const Job = require("../models/Job");
const { StatusCodes } = require("http-status-codes");
const { NotFoundError } = require("../errors");
const {
  extendQuery,
  fuzzySearchHandler,
  pageHandler,
} = require("../utils/extend-query");
const mongoose = require("mongoose");

const sortMap = {
  latest: "-createdAt",
  oldest: "createdAt",
  posAsc: "position",
  posDesc: "-position",
};
/**
 * 获取所有工作
 */
const getJobs = async (req, res) => {
  const queryObj = extendQuery(
    { ...req.query, createdBy: req.user.userId },
    {
      ...fuzzySearchHandler("company", req.query.company),
    }
  );
  const [skip, limit, page] = pageHandler(req.query);
  const jobs = await Job.find(queryObj)
    .sort(sortMap[req.query.sort] || "")
    .skip(skip)
    .limit(limit);

  const total = await Job.countDocuments(queryObj);

  res.status(StatusCodes.OK).json({
    data: { list: jobs, total, page },
  });
};

/**
 * 获取单个工作
 */
const getJob = async (req, res) => {
  const job = await Job.findOne({
    _id: req.params.id,
    createdBy: req.user.userId,
  });
  if (!job) {
    throw new NotFoundError(`No job with id ${req.params.id}`);
  }
  res.status(StatusCodes.OK).json({ data: job });
};

/**
 * 创建工作
 */
const createJob = async (req, res) => {
  const job = await Job.create({ ...req.body, createdBy: req.user.userId });
  res.status(StatusCodes.CREATED).json({
    data: job,
    msg: "创建成功",
  });
};

/**
 * 删除工作
 */
const removeJob = async (req, res) => {
  const job = await Job.findOneAndDelete({
    _id: req.params.id,
    createdBy: req.user.userId,
  });
  if (!job) {
    throw new NotFoundError(`Faild to remove job with id ${req.params.id}`);
  }
  res.status(StatusCodes.OK).json({
    data: {
      company: job.company,
      position: job.position,
      status: job.status,
    },
    msg: "删除成功",
  });
};

/**
 * 更新工作
 */
const updateJob = async (req, res) => {
  const job = await Job.findOneAndUpdate(
    { _id: req.params.id, createdBy: req.user.userId },
    req.body,
    {
      new: true,
      runValidators: true,
    }
  );
  if (!job) {
    throw new NotFoundError(`Faild to update job with id ${req.params.id}`);
  }
  res.status(StatusCodes.OK).json({
    data: {
      company: job.company,
      position: job.position,
      status: job.status,
    },
    msg: "更新成功",
  });
};

/**
 * 统计
 */
const showStats = async (req, res) => {
  let byStatus = await Job.aggregate([
    { $match: { createdBy: mongoose.Types.ObjectId(req.user.userId) } },
    { $group: { _id: "$status", count: { $sum: 1 } } },
  ]);

  byStatus = byStatus.reduce((acc, curr) => {
    const { _id: title, count } = curr;
    acc[title] = count;
    return acc;
  }, {});

  let byMonth = await Job.aggregate([
    { $match: { createdBy: mongoose.Types.ObjectId(req.user.userId) } },
    {
      $group: {
        _id: { year: { $year: "$createdAt" }, month: { $month: "$createdAt" } },
        count: { $sum: 1 },
      },
    },
    { $sort: { "_id.year": -1, "_id.month": -1 } },
    { $limit: 8}
  ]);

  byMonth = byMonth.map(item=>{
    return {
      name: `${item._id.year}-${item._id.month}`,
      count: item.count,
    }
  })

  res.status(StatusCodes.OK).json({
    data: {
      byStatus,
      byMonth,
    },
  });
};

module.exports = {
  getJobs,
  getJob,
  createJob,
  removeJob,
  updateJob,
  showStats,
};
